home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / mac / files / amiga / csrc720j.lzh / mb.c < prev    next >
C/C++ Source or Header  |  1993-04-20  |  16KB  |  754 lines

  1. /*
  2.  *  MB.C - 9/20/92 -  MailBox mainline code.
  3.  */
  4.  
  5. /*
  6.  *  Copyright (C) 1987, 1988
  7.  *  On Modules by H. N. Oredson
  8.  *  Copyright (C) 1988, 1989, 1990, 1991, 1992
  9.  *  By the CBBS Group.
  10.  *
  11.  *  It is being developed by the CBBS Group.
  12.  *  It may be freely copied for non-commercial use,
  13.  *  as long as this notice is retained.
  14.  *
  15.  *  This notice and Copyright apply to all modules
  16.  *  referenced by this module.
  17.  *
  18.  */
  19.  
  20. #include "mb.h"
  21.  
  22. #ifdef MCH_AMIGA
  23. extern char conn_direction;
  24. #ifndef MCH_SYSOP
  25. extern PORTS *devtnc;
  26. #endif
  27. #include "lock.h"
  28.  
  29. /* Allow user to specify the device name and unit number if they have
  30.    a multi-serial card. But default it to the standard device on unit zero
  31.    If ser_dev_name is zero then ser.c will use the standard name.
  32. */
  33. char *ser_dev_name = 0L;
  34. long unit = -1L;
  35.  
  36. extern short kambbs, thebox, debug , tapr_flag;
  37. long BaudRate;
  38. short left = 0, top = 0, width = 640, height = 256;
  39. extern int daylight;
  40. #else
  41. char  *ver = "\nC-BBS V7.2, 20 SEP 1992\n\n";
  42. char  *vers = "[CBBS-7.20-H$]\n";
  43. #endif
  44. char  *nullstr = "";
  45.  
  46. PORTS *porthd = NULL;
  47. PORTS *cport  = NULL;
  48. PORTS *port;
  49.  
  50. int   scrmax, dirmax, log_mon;
  51. TMP   *tmp;
  52. MLM   *motd;
  53. char  *helpfile, *infofile;
  54. char  *bbmenu, *symenu, *rmenus, *mumsg;
  55. char  *reqmsg, *qth, *keylst;
  56. char  *mcant, *mdone, *mfind, *mexst, *mnfile, *mnmsg;
  57. char  *mprot, *mtime, *mwhat, *mnport, *mndir, *minuse;
  58. char  achar, rchar, tchar, wchar;
  59. word  s_param, p_window, c_flag, b_flag;
  60. byte  s_mart, s_prompt, s_flag, unt_hr;
  61. char  scmd[24];
  62.  
  63. #ifdef MCH_AMIGA
  64. #ifndef MCH_SYSOP
  65. char hostport = 'A';
  66. #else
  67. char hostport = '1';
  68. #endif
  69. #endif
  70.  
  71. #ifdef MCH_AMIGA
  72. short timezone = -900;     /* Initialize to impossible number of minutes */
  73. extern char tmpstr[];
  74. #endif
  75. main(argc, argv)
  76. int argc;
  77. char *argv[];
  78. {
  79. #ifdef MCH_AMIGA
  80.    char *cp;
  81.    short i;
  82.  
  83. /* Might as well do a quick check to make sure the locker is there.
  84. */
  85.    if(FindPort((UBYTE *)LOCK_NAME) == 0L) {
  86.       printf("Can't find the locker process\n");
  87.       exit(10);
  88.    }
  89.    /* Get the environment variable timezone if it is set.
  90.       Doing it here allows the user to override the value of TZ_CHU
  91.       with the -z argument.
  92.    */
  93.    timezone = gettz("");
  94.    get_reject();
  95.    while(argc > 1) {
  96.       if(argv[1][0] == '-') {
  97.          switch(tolower(argv[1][1])) {
  98.  
  99.          /* allow user to specify the position of the window on the screen
  100.             -wL/T/W/H
  101.          */
  102.          case 'w':
  103.             cp = &argv[1][2];
  104.             left = atoi(cp);
  105.             while(*cp && (*cp != '/'))cp++;
  106.             if(*cp == 0)break;
  107.             cp++;
  108.             top = atoi(cp);
  109.             while(*cp && (*cp != '/'))cp++;
  110.             if(*cp == 0)break;
  111.             cp++;
  112.             width = atoi(cp);
  113.             while(*cp && (*cp != '/'))cp++;
  114.             if(*cp == 0)break;
  115.             cp++;
  116.             height = atoi(cp);
  117.             setwindow(left,top,width,height);
  118.             break;
  119.  
  120.          /* In multi mode, specify the port which this copy will open
  121.          */
  122.          case 'p':
  123.             hostport = toupper(argv[1][2]);
  124.             break;
  125.  
  126.          case 'n':      /* Serial port name for multi-serial users */
  127.             ser_dev_name = &argv[1][2];
  128.             break;
  129.          case 'u':      /* Serial port unit number for multi-serial */
  130.             unit = (long)atoi(&argv[1][2]);
  131.             break;
  132.  
  133.          case 'd':
  134.             debug = 1;
  135.             break;
  136. /* Baud rate is in the host driver */
  137.          case 'b':
  138.             BaudRate = atol(&argv[1][2]);
  139.             break;
  140.          case 't':
  141.             /* tell serial read routine to strip high bit off all bytes
  142.                read from the TNC because it is a TAPR upgrade kit that
  143.                generates NO parity only with the parity bit forced to one
  144.             */
  145.             tapr_flag++;
  146.             break;
  147.          case 'z':
  148.             /* Specify the timezone so that you can keep your amiga
  149.                on your local time but have the time in messages converted
  150.                to UTC. format is -z[-]hh[:mm][d]
  151.                Times WEST of Greenwich are POSITIVE.
  152.                Times EAST of Greenwich are NEgative.
  153.                The optional minutes ":mm" allows places like Newfoundland
  154.                to specify their zone as 3:30.
  155.                If the optional letter 'd' is present at the end of the
  156.                string, then your local time zone is adjusted for daylight
  157.                savings time.
  158.  
  159.                The -z argument, if set, overrides any value in the TZ_CHU
  160.                environment variable.
  161.             */
  162.             timezone = gettz(&argv[1][2]);
  163.             break;
  164.          }
  165.          argc--;
  166.          argv++;
  167.          continue;
  168.       }
  169.       break;
  170.    }
  171.    /* Just make sure that there isn't already a port with our name on it */
  172.    if(testport()) {
  173.       exit(1);
  174.    }
  175.    /* Call routine that reads my modified init() so that the config.mb
  176.       file is opened early to permit options in config.mb to be read
  177.       before the window and serial port are opened. This allows options
  178.       to be used that affect the opening of the window or serial parameters.
  179.    */
  180.    if (argc > 1)i = setinit(argv[1]); else i = setinit("config.mb");
  181.    if(i)exit(1);
  182.    printf("Serial device name = %s  unit = %ld\n",ser_dev_name,unit);
  183.    if(initser()) {
  184.       printf("error opening serial port\n");
  185.       exit(1);
  186.    }
  187.    if(openterm()) {
  188.       printf("error opening terminal\n");
  189.       cleanser();
  190.       exit(1);
  191.    }
  192.  
  193.    if(inittimer()) {
  194.       printf("error opening timer\n");
  195.       cleanser();
  196.       closeterm();
  197.       exit(1);
  198.    }
  199.  
  200. /* This does more than the quick check at the beginning of main() so
  201.    don't remove this call.
  202. */
  203.    if(i = findlock()) {
  204.       printf("Can't find the Lock process - %d\n",i);
  205.       cleanser();
  206.       closeterm();
  207.       exit(1);
  208.    }
  209. /* This allows the port driver to count how many processes are running
  210.    without having to be told
  211. */
  212.    setbusy();
  213.  
  214. /* Up to this point all routines MUST do their own cleaning up and then
  215.    exit() directly. AFTER setbusy() has been called any further errors
  216.    should cause done() to be called because done() calls clrbusy.
  217.    Otherwise the locking program will have an incorrect count of the number
  218.    of active processes.
  219.    The EXCEPTION to this rule is inittnc() which already cleared up its
  220.    own mess, so I just added a clrbusy as well, rather than try to fix
  221.    it up to use done().
  222. */
  223.  
  224. #endif
  225.  
  226.  
  227.   if (argc > 1) init(argv[1]); else init("config.mb");
  228.  
  229. #ifdef MCH_AMIGA
  230.    /* Compute the first Sunday in April and last Sunday in October
  231.       if daylight savings is being used.
  232.    */
  233.    dstdates();
  234.    if(timezone != -900) {
  235.       i = timezone;
  236.       sprintf(tmpstr,"Timezone = %c%d:%02d %s\n",
  237.                        i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60,
  238.                        daylight?"(DST)":"");
  239.       ttputs(tmpstr);
  240.       printf("%s",tmpstr);
  241.       i = dst(timezone);
  242.       if(i != timezone) {
  243.          sprintf(tmpstr,"DST time = %c%d:%02d\n",
  244.                        i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60);
  245.          ttputs(tmpstr);
  246.          printf("%s",tmpstr);
  247.       }
  248.    }
  249.    else {
  250.       cp = "Timezone not set - Assume UTC and no DST\n";
  251.       printf("%s",cp);
  252.       ttputs(cp);
  253.       timezone = 0;
  254.       daylight = 0;
  255.    }
  256. #endif
  257.  
  258.  
  259. #ifdef MCH_AMIGA
  260. /* Open up the AREXX public port so that the waitport program can be used
  261.    to start up several CBBS copies in sequence and also allows communication
  262.    from outside processes and between multiple 'mb' processes.
  263. */
  264.    if(open_rexx())done(1);
  265. #endif
  266.   while (true)
  267.   {
  268.     s_mart = 0;
  269. #ifdef MCH_AMIGA
  270.     kambbs = 0;
  271.     thebox = 0;
  272.     conn_direction = ' ';
  273.     user_title("");
  274.     titles();
  275. #endif
  276.     do_idle();
  277.     setbusy();
  278.     login();
  279. #ifndef MCH_AMIGA
  280.     if (!(port->mode & exclude)) do_cmds();
  281. #else
  282. /*FIX 8  ignore idle terminal caused by monitoring data that looks like a
  283.          "*** CONNected" message.
  284. */
  285.     if(!(port->mode & idle)) {
  286.        if(!(port->mode & exclude)) do_cmds();
  287.     }
  288. #endif
  289.     logo();
  290.   }
  291. }
  292.  
  293. do_cmds()
  294. {
  295.   register PORTS *p;
  296.   register char  *i, *o;
  297.  
  298.   p = port;
  299.  
  300.   while(true)
  301.   {
  302.     prompt();
  303.     getcmd();
  304.     if (p->mode & gone) return;
  305.  
  306. /*
  307.  *  Console broke in on a user?
  308.  */
  309.  
  310.     if (p->flags & p_opreq)
  311.     {
  312.       p->flags clrbit p_opreq;
  313.       prtx(talkm1);
  314.       if (p->tmode)
  315.       {
  316.         cmdtnc();
  317.         convtnc();
  318.       }
  319.       ioport(cport);
  320.       prtx(mumsg);
  321.       cport->fl = NULL;
  322.       term(p);
  323.       ioport(p);
  324.       tncstate();
  325.       if (p->tmode) trantnc(); else convtnc();
  326.       if (p->mode & gone) return;
  327.     }
  328.  
  329. /*
  330.  *  Check for LINK.
  331.  *  Require "LINKED to" to be first command.
  332.  */
  333.  
  334.     else if (islink(p->line))
  335.     {
  336.       if (p->cmdcnt) p->msg = mwhat; else
  337.       {
  338.    strcpy(p->line, p->line + 14);
  339.    logina(true);
  340.    remnl(p->line);
  341.    log('C', 'L', ' ', p->line);
  342.    if (p->mode & exclude) return;
  343.       }
  344.     }
  345.  
  346. /*
  347.  *  Must be a command.
  348.  */
  349.  
  350.     else
  351.     {
  352.       docmd();
  353.       if (p->errors > p->errmax) p->mode = forced;
  354.       if (p->mode & (gone | idle | logout)) return;
  355.     }
  356.   }
  357. }
  358.  
  359. /*
  360.  *  Q command: exit to DOS.
  361.  */
  362.  
  363. #ifndef MCH_AMIGA
  364. done()
  365. {
  366.   byte pflg;
  367.  
  368.   if (sure()) return;
  369. #else
  370. extern short done_flag;
  371. done(askflag)
  372. int askflag;
  373. {
  374.    byte pflg;
  375.    if(!askflag && sure()) return;
  376.    done_flag = 0;
  377.    cursor_off();
  378.    close_rexx();
  379. #endif
  380.   upduser(cport->user);
  381.   log('X', 'Q', ' ', nullstr);
  382.   clslog();
  383.   clsusr();
  384.   clsmsg();
  385.   clsmon();
  386.   iooff();
  387.   clrbusy();
  388.   pflg = getp_flag();
  389.   putp_flag(pflg clrbit p_window);
  390. #ifdef MCH_AMIGA
  391.    endtimer();
  392.    cleanser();
  393.    freefcb();
  394.    closeterm();
  395.    stoplock();
  396. #endif
  397.   exit(0);
  398. }
  399.  
  400. /*
  401.  *  Give the user a prompt.
  402.  */
  403.  
  404. prompt()
  405. {
  406.   register PORTS *p, *tp;
  407.  
  408.   p = port;
  409.   if (p->msg isnt NULL) prtx(p->msg);
  410.   p->msg = NULL;
  411.  
  412. /*
  413.  *  Tell sysop who this is.
  414.  */
  415.  
  416.   if (p isnt cport) { ioport(cport); prtx(mumsg); ioport(p); }
  417.  
  418. /*
  419.  *  Show any connect request seen on the user port.
  420.  */
  421.  
  422.   if (p->flags & p_req) prtx(reqmsg);
  423.   p->flags clrbit p_req;
  424.  
  425. /*
  426.  *  Bleed off any connect requests on other ports.
  427.  */
  428.  
  429. /* There aren't any other ports on the AMIGA */
  430. #ifndef MCH_AMIGA
  431.   for (tp = porthd; tp isnt NULL; tp = tp->next) if (tp->mode & idle)
  432.   if ((tp->dev is p_tnc) and (tp isnt p))
  433.   {
  434.     ioport(tp);
  435.     while (instat()) getdat();
  436.   }
  437.   ioport(p);
  438. #endif
  439. /*
  440.  *  Display the prompt.
  441.  */
  442.  
  443.   curtim();
  444.   switch (p->mode)
  445.   {
  446.     case local :
  447.     case sysop :
  448.       prtx(symenu);
  449.       break;
  450.  
  451.     case remote:
  452.       if (!(p->user->options & u_bbs))
  453.       {
  454.    if (s_prompt & s_p_name) if (!(p->user->state & u_name)) prtx(um[4]);
  455.    if (s_prompt & s_p_home) if (!(p->user->state & u_home)) prtx(um[5]);
  456.    if (s_prompt & s_p_zip)  if (!(p->user->state & u_zip))  prtx(um[6]);
  457.    if (s_prompt & s_p_qth)  if (!(p->user->state & u_qth))  prtx(um[7]);
  458.       }
  459.  
  460. #ifndef MCH_AMIGA
  461.       if (p->user->options & (u_bbs | u_expert)) prtx(bbmenu); else prtx(rmenus);
  462. #else
  463.       if(p->user->options & u_bbs) outstr(">\n");
  464.       else if (p->user->options & u_expert) prtx(bbmenu);
  465.       else prtx(rmenus);
  466. #endif
  467.       break;
  468.   }
  469. }
  470.  
  471. /*
  472.  *  Log the user off.
  473.  *  Do any defered remote sysop command.
  474.  */
  475.  
  476. logo()
  477. {
  478.   register PORTS *p;
  479.   register PORTS *tp;
  480.   register char t;
  481.  
  482.   p = port;
  483.  
  484.   switch(p->mode)
  485.   {
  486.     case idle   : t = 'A'; break; /* Init bbs logout */
  487.     case logout : t = 'B'; break;
  488.     case discon : t = 'D'; break;
  489.     case exclude: t = 'E'; break;
  490.     case forced : t = 'F'; distnc(); break;
  491.     case timeout: t = 'T'; prtx(mtime); break;
  492.     default     : t = '?'; break;
  493.   }
  494.  
  495. #ifndef MCH_AMIGA
  496.   log('X', t, ' ', nullstr);
  497. #else
  498.   log('X', t, port->id , nullstr);
  499. #endif
  500.  
  501. /*
  502.  *  If any port was used in terminal mode by the console,
  503.  *  disconnect it.
  504.  */
  505.  
  506.   if (p->dev is p_console)
  507.   for (tp = porthd; tp isnt NULL; tp = tp->next)
  508.   if (tp->flags & p_term)
  509.   {
  510.     ioport(tp);
  511.     tp->mode = remote;
  512.     distnc();
  513.     tp->mode = idle;
  514.     tp->flags clrbit p_term;
  515.   }
  516.  
  517.   ioport(p);
  518.  
  519. /*
  520.  *  Change TNC back to "standard" if was in "sysop" mode.
  521.  *  May have just THOUGHT we discon, REALLY disconnect.
  522.  */
  523.  
  524.   if (p->dev is p_tnc)
  525.   {
  526.     if (p->flags & p_clrsys) mkrem();
  527.     p->mode = remote;
  528.     distnc();
  529.   }
  530.   if (p->dev is p_serial) p->flags clrbit p_trans;
  531. #ifdef MCH_AMIGA
  532.   if (p->dev is p_nulmdm) p->flags clrbit p_trans;
  533. #endif
  534. #ifndef MCH_SYSOP
  535. /* Hang up a modem */
  536.    if(p->dev is p_serial) {
  537.       force_modem();
  538.    }
  539. /* If it was the console but the serial device is a modem, then allow
  540.    phone to ring again.
  541. */
  542.    if(p->dev is p_console) {
  543.       if(devtnc->dev is p_serial) {
  544.          tp = p;
  545.          ioport(devtnc);
  546.          outstr("ATS0=2\n");
  547.          waitcmd(2);
  548.          ioport(tp);
  549.       }
  550.    }
  551. #endif
  552.   p->mode = idle;
  553.  
  554.   upduser(p->user);
  555.  
  556. /*
  557.  *  If there was a "defered remote sysop command" do it.
  558.  */
  559.  
  560.   ioport(cport);
  561.   if (s_param & s_cmd)
  562.   {
  563.     s_param clrbit s_cmd;
  564.     strcpy(cport->line, scmd);
  565.     parse();
  566.     wait(10);               /* Give sysop chance to get HIS system online */
  567.     cport->mode = local;    /* Do command as if console did it */
  568.     docmd();
  569.     cport->mode = idle;
  570.   }
  571.  
  572.   clnlog();
  573.   clsusr();
  574.   setfwd();
  575.   clsmsg();
  576. }
  577.  
  578. /*
  579.  *  MailBox is idle.
  580.  *  See if there is anything to do, and do it.
  581.  *  If nothing to do, wait for connect.
  582.  */
  583.  
  584. #ifndef MCH_AMIGA
  585. do_idle()
  586. {
  587.   register PORTS *p;
  588.   register short curmin, lastmin, curmon;
  589.  
  590.   for (p = porthd; p isnt NULL; p = p->next) p->ec = p->ecmon;
  591.  
  592.   getc_flag();
  593.   if (c_flag & p_window) acmd();
  594.  
  595.   allon();  /* Turn on monitoring and connects */
  596.   clrbusy();
  597.   curtim();
  598.   curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
  599.   while(true)
  600.   {
  601.  
  602. /*
  603.  *  Check the port command flag to see if another window has
  604.  *  issued a command request. If so setup and do the command.
  605.  */
  606.  
  607.     getc_flag();
  608.     if (c_flag & p_window)
  609.     {
  610.       setbusy();
  611.       alloff();
  612.       acmd();
  613.       allon();
  614.       clrbusy();
  615.     }
  616.  
  617.     lastmin = curmin;
  618.     curtim();
  619.     curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
  620.     curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
  621.  
  622. /*
  623.  *  Once each minute:
  624.  *  Forward now, if it is time on any port.
  625.  */
  626.  
  627.     if (curmin isnt lastmin) afwd(curmin);
  628.     if (s_param & s_log_on) if (curmon isnt log_mon) chglog();
  629.  
  630. /*
  631.  *  Look for a login.
  632.  */
  633.  
  634.     for (p = porthd; p isnt NULL; p = p->next)
  635.     {
  636.       ioport(p);
  637.       if (instat()) switch(p->dev)
  638.       {
  639.    case p_serial:
  640.      p->flags clrbit p_give;
  641.      getdat();
  642.      p->flags setbit p_give;
  643.      if (iscon(p->line)) return;
  644.      break;
  645.  
  646.    case p_tnc:
  647.      p->flags clrbit p_give;
  648.      getdat();
  649.      p->flags setbit p_give;
  650.      if (iscon(p->line)) return;
  651.      monitor();
  652.      break;
  653.  
  654.    case p_console:
  655.      if (inchar() is wchar) return;
  656.      break;
  657.       }
  658.       p->flags setbit p_give;
  659.     }
  660.   }
  661. }
  662. #endif
  663. /*
  664.  *  Do commands retrieved from the bios.
  665.  */
  666. #ifndef MCH_AMIGA
  667. acmd()
  668. {
  669.    char need_msg = false;
  670.    char notime = false;
  671.  
  672.    port->mode = local;
  673.    getcomd();
  674.    if (s_flag & s_dv) begin_lock();
  675.    if (isdigit(port->opt2))
  676.    {
  677.      notime = true;
  678.      port->opt2 = port->opt2 ^ 0x70;
  679.    }
  680.    if ((port->opt1 is 'X') and (findport(port->opt2)))
  681.    {
  682.      if (notime) port->opt2 = ' '; else port->opt2 = 'I';
  683.      readmsg();
  684.      readusr();
  685.      need_msg = true;
  686.    }
  687.    getc_flag();
  688.    putc_flag( c_flag clrbit p_window);
  689.    if (s_flag & s_dv) end_lock();
  690.    if (need_msg or (port->opt2 is 'H'))
  691.    {
  692.      sprintf(port->line, "%c%c", port->opt1, port->opt2);
  693.      parse();
  694.      docmd();
  695.    }
  696.    if (need_msg)
  697.    {
  698.      clnlog();
  699.      setfwd();
  700.      clsmsg();
  701.      clsusr();
  702.    }
  703.    port->mode = idle;
  704. }
  705. #endif
  706. #ifdef MCH_AMIGA
  707. #ifndef MCH_SYSOP
  708. acmd()
  709. {
  710.    char need_msg = false;
  711.    char notime = false;
  712.    port->mode = local;
  713.    if (s_flag & s_dv) begin_lock();
  714.    if(port->opt1 == 'X')
  715.    {
  716.      readmsg();
  717.      readusr();
  718.      need_msg = true;
  719.    }
  720.    if (s_flag & s_dv) end_lock();
  721.    if (need_msg or (port->opt2 is 'H'))
  722.    {
  723.      sprintf(port->line, "%c%c", port->opt1, port->opt2);
  724.      parse();
  725.      docmd();
  726.    }
  727.    if (need_msg)
  728.    {
  729.      clnlog();
  730.      setfwd();
  731.      clsmsg();
  732.      clsusr();
  733.    }
  734.    port->mode = idle;
  735. }
  736. #endif
  737. #endif
  738. /* Bring this here from mbfwd to save having to make a separate sysop
  739.    version of mbfwd (Otherwise it could stay there)
  740. */
  741. #ifdef MCH_SYSOP
  742. all_fwd()
  743. {
  744.   word pflg;
  745.   port->opt1 = 'X';
  746.   putcomd( port->opt1, port->opt2 );
  747. #ifndef MCH_AMIGA
  748.   pflg = getp_flag();
  749.   putc_flag (pflg);
  750. #endif
  751.   port->mode = logout;
  752. }
  753. #endif
  754.